package pages;

import constant.ExceptionConstant;
import constant.MessageConstant;
import constant.PatternConstant;
import pojo.Student;
import pojo.StudentCondition;
import utils.JDBCUtil;
import utils.StudentUtil;

import java.sql.SQLException;
import java.util.List;
import java.util.Scanner;

public class StudentPage {
    private static final Scanner scanner = new Scanner(System.in);

    //数据缓存，缓存数据库中的所有学生数据
    private static final List<Student> listStudent;

    static {
        try {
            listStudent = JDBCUtil.selectSudent();
        } catch (SQLException e) {
            throw new RuntimeException(ExceptionConstant.CACHE_GET_EXCEPTION);
        }
    }

    public StudentPage() {
        systemPage();
    }

    private static void systemPage() {
        while (true) {
            System.out.println("======== 系统页面 ========");
            System.out.println("0. 返回到主页面");
            System.out.println("1. 添加学生");
            System.out.println("2. 删除学生");
            System.out.println("3. 修改学生");
            System.out.println("4. 查询所有学生");
            System.out.println("5. 条件查询学生");
            System.out.println("======== 系统页面 ========");
            System.out.print("请输入你的选择: ");
            String choice = scanner.next();

            switch (choice) {
                case "0":
                    new IndexPage();
                    return;
                case "1":
                    try {
                        addStudent();
                    } catch (SQLException e) {
                        throw new RuntimeException(ExceptionConstant.SQL_EXECUTE_EXCEPTION);
                    }
                    return;
                case "2":
                    try {
                        deleteStudent();
                    } catch (SQLException e) {
                        throw new RuntimeException(ExceptionConstant.SQL_EXECUTE_EXCEPTION);
                    }
                    return;
                case "3":
                    try {
                        updateStudent();
                    } catch (SQLException e) {
                        throw new RuntimeException(ExceptionConstant.SQL_EXECUTE_EXCEPTION);
                    }
                    return;
                case "4":
                    selectAllStudents();
                    return;
                case "5":
                    try {
                        selectStudentsByCondition();
                    } catch (SQLException e) {
                        throw new RuntimeException(ExceptionConstant.SQL_EXECUTE_EXCEPTION);
                    }
                    return;
                default:
                    System.err.println(MessageConstant.NOT_CHOICE);
            }
        }
    }

    /**
     * 添加学生
     */
    private static void addStudent() throws SQLException {
        //创建学生对象存储用户输入的信息
        Student student = new Student();

        //获取学号并进行校验
        while (true) {
            System.out.println("请输入学号：");
            String sno = scanner.next();
            if (StudentUtil.getIndexBySno(listStudent, sno) >= 0) {
                System.err.println(MessageConstant.SNO_ALREADY_EXIST);
                continue;
            }
            student.setSno(sno);
            break;
        }

        //获取姓名
        System.out.println("请输入姓名：");
        String name = scanner.next();
        student.setName(name);

        //获取性别并进行校验
        while (true) {
            System.out.println("请输入性别(男或女,输入0跳过)：");
            String gender = scanner.next();
            if(gender.equals("0")){
                student.setGender(null);
                break;
            }
            if (!gender.equals("男") && !gender.equals("女")) {
                System.err.println(MessageConstant.GENDER_INPUT_ERROR);
                continue;
            }
            student.setGender(gender.equals("男") ? 1 : 2);
            break;
        }

        //获取年龄
        while (true) {
            System.out.println("请输入年龄(输入0跳过)：");
            String age = scanner.next();
            if(age.equals("0")){
                student.setAge(null);
                break;
            }
            if (!age.matches(PatternConstant.AGE_PATTERN)) {
                System.err.println(MessageConstant.AGE_INPUT_ERROR);
                continue;
            }
            student.setAge(Integer.parseInt(age));
            break;
        }

        //获取身份证号并进行校验
        while (true) {
            System.out.println("请输入身份证号(输入0跳过)：");
            String idNumber = scanner.next();
            if(idNumber.equals("0")){
                student.setId_number(null);
                break;
            }
            if (StudentUtil.getIndexByIdNumber(listStudent, idNumber) >= 0) {
                System.err.println(MessageConstant.ID_NUMBER_ALREADY_EXIST);
                continue;
            } else if (!idNumber.matches(PatternConstant.ID_NUMBER_PATTERN)) {
                System.err.println(MessageConstant.ID_NUMBER_FORMAT_ERROR);
                continue;
            }
            student.setId_number(idNumber);
            break;
        }

        //获取家庭住址
        System.out.println("请输入家庭住址(输入0跳过)：");
        String address = scanner.next();
        student.setAddress(address.equals("0") ? null : address);

        //获取手机号并进行校验
        while (true) {
            System.out.println("请输入手机号(输入0跳过)：");
            String phone = scanner.next();
            if(phone.equals("0")){
                student.setPhone(null);
                break;
            }
            if (!phone.matches(PatternConstant.PHONE_PATTERN)) {
                System.err.println(MessageConstant.PHONE_FORMAT_ERROR);
                continue;
            }
            student.setPhone(phone);
            break;
        }

        //获取院系
        System.out.println("请输入院系(输入0跳过)：");
        String depart = scanner.next();
        student.setDepart(depart.equals("0") ? null : depart);

        //获取专业
        System.out.println("请输入专业(输入0跳过)：");
        String major = scanner.next();
        student.setMajor(major.equals("0") ? null : major);

        //获取所在班级
        System.out.println("请输入所在班级(如23计科2班,输入0跳过)：");
        String nowClass = scanner.next();
        student.setNow_class(nowClass.equals("0") ? null : nowClass);

        //插入学生信息到数据库和本地缓存
        JDBCUtil.insert(student);
        listStudent.add(student);
        System.out.println("添加学生成功");
        systemPage();
    }

    /**
     * 删除学生
     */
    private static void deleteStudent() throws SQLException {
        //获取学生学号
        System.out.println("请输入要删除的学生学号: ");
        String sno = scanner.next();

        //判断学号是否存在
        int index = StudentUtil.getIndexBySno(listStudent, sno);
        if (index == -1) {
            System.err.println(MessageConstant.SNO_NOT_EXIST_NOT_DELETE);
            systemPage();
        } else {
            //删除数据库和缓存中的学生信息
            JDBCUtil.delete(sno);
            listStudent.remove(index);
            System.out.println("删除成功");
            systemPage();
        }
    }

    /**
     * 修改学生信息
     */
    private static void updateStudent() throws SQLException {
        System.out.print("请输入要修改的学生学号：");
        String sno = scanner.next();

        int index = StudentUtil.getIndexBySno(listStudent, sno);
        if (index == -1) {
            System.err.println(MessageConstant.SNO_NOT_EXIST_NOT_UPDATE);
            systemPage();
            return;
        }
        Student student = listStudent.get(index);

        System.out.println("请输入新的姓名(不修改输入0)：");
        String name = scanner.next();
        if (!name.equals("0")) {
            student.setName(name);
        }

        while (true) {
            System.out.println("请输入新的性别(男或女，不修改输入0)：");
            String gender = scanner.next();
            if (!gender.equals("男") && !gender.equals("女") && !gender.equals("0")) {
                System.err.println(MessageConstant.GENDER_INPUT_ERROR);
                continue;
            }
            if (gender.equals("0")) {
                break;
            }
            student.setGender(gender.equals("男") ? 1 : 2);
            break;
        }

        while (true) {
            System.out.println("请输入新的年龄(不修改输入0)：");
            String age = scanner.next();
            if(age.equals("0")){
                break;
            }
            if (!age.matches(PatternConstant.AGE_PATTERN)) {
                System.err.println(MessageConstant.AGE_INPUT_ERROR);
                continue;
            }
            student.setAge(Integer.parseInt(age));
            break;
        }


        while (true) {
            System.out.println("请输入新的身份证号(不修改输入0)：");
            String idNumber = scanner.next();
            if (idNumber.equals("0")) {
                break;
            }
            if (StudentUtil.getIndexByIdNumber(listStudent, idNumber) >= 0 && !idNumber.equals(student.getId_number())) {
                System.err.println(MessageConstant.ID_NUMBER_ALREADY_EXIST);
                continue;
            }
            if (!idNumber.matches(PatternConstant.ID_NUMBER_PATTERN)) {
                System.err.println(MessageConstant.ID_NUMBER_FORMAT_ERROR);
                continue;
            }
            student.setId_number(idNumber);
            break;
        }

        System.out.println("请输入新的家庭住址(不修改输入0)：");
        String address = scanner.next();
        if (!address.equals("0")) {
            student.setAddress(address);
        }

        while (true) {
            System.out.println("请输入新的手机号(不修改输入0)：");
            String phone = scanner.next();
            if (phone.equals("0")) {
                break;
            }
            if (!phone.matches(PatternConstant.PHONE_PATTERN)) {
                System.err.println(MessageConstant.PHONE_FORMAT_ERROR);
                continue;
            }
            student.setPhone(phone);
            break;
        }

        System.out.println("请输入新的院系(不修改输入0)：");
        String depart = scanner.next();
        if (!depart.equals("0")) {
            student.setDepart(depart);
        }

        System.out.println("请输入新的专业(不修改输入0)：");
        String major = scanner.next();
        if (!major.equals("0")) {
            student.setMajor(major);
        }

        System.out.println("请输入新的所在班级(不修改输入0)：");
        String nowClass = scanner.next();
        if (!nowClass.equals("0")) {
            student.setNow_class(nowClass);
        }

        JDBCUtil.update(student);
        System.out.println("修改成功");
        systemPage();
    }

    /**
     * 查询所有学生信息
     */
    private static void selectAllStudents() {
        StudentUtil.printList(listStudent);
        systemPage();
    }

    /**
     * 根据学号模糊查询
     */
    private static void selectStudentsByCondition() throws SQLException {
        StudentCondition studentCondition = new StudentCondition();

        //获取学号并进行校验
        System.out.println("请输入学号(跳过输入0)：");
        String sno = scanner.next();
        studentCondition.setSno(sno.equals("0") ? null : sno);

        //获取姓名
        System.out.println("请输入姓名(跳过输入0)：");
        String name = scanner.next();
        studentCondition.setName(name.equals("0") ? null : name);

        //获取性别并进行校验
        System.out.println("请输入性别(男或女，跳过输入0)：");
        String gender = scanner.next();
        //如果性别输入不是男或女，匹配一个不可能值(比如3)
        studentCondition.setGender(gender.equals("0") ? null : (gender.equals("男") ? 1 : (gender.equals("女") ? 2 : 3)));

        //获取年龄范围
        System.out.println("请输入年龄最小值(跳过输入0)：");
        String beginAge = scanner.next();
        System.out.println("请输入年龄最大值(跳过输入0)：");
        String endAge = scanner.next();
        //一致性校验（假设允许beginAge大于endAge存在）
        //1.如果两个值有一个不是0且不满足正则AGE_PATTERN，就设置beginAge>endAge，使查询结果为空
        //2.如果两个值都满足正则（0排除），若变量值为0，就设置属性为null，开放对应的边界；若变量值不为0，就设置原来的值
        if(((!beginAge.equals("0") && !beginAge.matches(PatternConstant.AGE_PATTERN))) || ((!endAge.equals("0")) && !endAge.matches(PatternConstant.AGE_PATTERN))){
            studentCondition.setBeginAge(2);
            studentCondition.setEndAge(1);
        }else{
            studentCondition.setBeginAge(beginAge.equals("0") ? null : Integer.parseInt(beginAge));
            studentCondition.setEndAge(endAge.equals("0") ? null : Integer.parseInt(endAge));
        }

        //获取身份证号并进行校验(之所以校验年龄而不校验其他正则，是因为年龄为整数类型，如果不匹配正则，会在parseInt处出错，导致系统被迫停止，影响体验)
        System.out.println("请输入身份证号(跳过输入0)：");
        String idNumber = scanner.next();
        studentCondition.setId_number(idNumber.equals("0") ? null : idNumber);

        //获取家庭住址
        System.out.println("请输入家庭住址(跳过输入0)：");
        String address = scanner.next();
        studentCondition.setAddress(address.equals("0") ? null : address);

        //获取手机号并进行校验
        System.out.println("请输入手机号(跳过输入0)：");
        String phone = scanner.next();
        studentCondition.setPhone(phone.equals("0") ? null : phone);

        //获取院系
        System.out.println("请输入院系(跳过输入0)：");
        String depart = scanner.next();
        studentCondition.setDepart(depart.equals("0") ? null : depart);

        //获取专业
        System.out.println("请输入专业(跳过输入0)：");
        String major = scanner.next();
        studentCondition.setMajor(major.equals("0") ? null : major);

        //获取所在班级
        System.out.println("请输入所在班级(跳过输入0)：");
        String nowClass = scanner.next();
        studentCondition.setNow_class(nowClass.equals("0") ? null : nowClass);

        //根据条件获取学生记录
        List<Student> list = JDBCUtil.selectStudent(studentCondition);

        //遍历记录
        StudentUtil.printList(list);
        systemPage();
    }
}